package org.greatlogic.gwtfilereaderwidget.client.xml;

import org.greatlogic.gwtfilereaderwidget.client.xml.XMLEnums.EXMLEventType;
/**
 * A collection of helper methods for the StAX parser.
 */
public class XMLHelper {
//--------------------------------------------------------------------------------------------------
private XMLStreamReader _reader;
//--------------------------------------------------------------------------------------------------
public XMLHelper(final CharSequence filenameOrXML) throws XMLStreamException {
  if (filenameOrXML == null || filenameOrXML.length() == 0) {
    throw new IllegalArgumentException();
  }
  //  Reader reader;
  //  if (filenameOrXML.charAt(0) == '<') {
  //    reader = new StringReader(filenameOrXML.toString());
  //  }
  //  else {
  //    reader = new FileReader(filenameOrXML.toString());
  //  }
  _reader = XMLInputFactory.newInstance().createXMLStreamReader(null);//reader);
} // XMLHelper()
//--------------------------------------------------------------------------------------------------
/**
* Finds the next element with a specific tag and optional value. On exit the reader will be
* positioned on the end tag for the element.
* @param elementTag The tag that is used to locate the element.
* @return The value associated with the element. This will be an empty string if there is no
* value.
*/
public String findNextElementUsingTag(final String elementTag) throws XMLStreamException {
  return findNextElementUsingTagAndValue(elementTag, null, false);
} // findNextElementUsingTag()
//--------------------------------------------------------------------------------------------------
/**
* Finds the next element with a specific tag and optional value.
* @param matchTag The tag that is used to locate the element.
* @param matchValue If this value is null then the method will return as soon as the first
* element that matches the requested tag is found; if the value is not null then the method will
* return only when an element with a matching tag is found and the value of the element equals
* the value of this parameter.
* @param trimValue Indicates that the element value is to be trimmed before comparing it to the
* requested value.
* @return The value associated with the element. This will be an empty string if there is no
* value.
*/
public String findNextElementUsingTagAndValue(final String matchTag, final String matchValue,
                                              final boolean trimValue) throws XMLStreamException {
  String result = null;
  EXMLEventType eventType;
  boolean endOfSearch;
  do {
    eventType = getEventType();
    if (eventType == EXMLEventType.StartElement) {
      QName name = _reader.getName();
      if (name.getLocalPart().equalsIgnoreCase(matchTag)) {
        eventType = EXMLEventType.lookupUsingStreamConstant(_reader.next());
        String elementValue = "";
        if (eventType == EXMLEventType.Characters) {
          elementValue = getCharactersValue();
        }
        if (matchValue == null ||
            matchValue.equalsIgnoreCase(trimValue ? elementValue.trim() : elementValue)) {
          result = elementValue;
        }
      }
    }
    endOfSearch = result != null || eventType == EXMLEventType.EndDocument;
    if (!endOfSearch) {
      _reader.next();
    }
  } while (!endOfSearch);
  return result;
} // findNextElementUsingTagAndValue()
//--------------------------------------------------------------------------------------------------
/**
 * Returns the value of the next character element value. On entry the stream reader should be on
 * the character value or on the element tag prior to the character value. On exit the reader will
 * be positioned on the end element tag.
 * @return The value for the next element.
 */
public String getCharactersValue() throws XMLStreamException {
  String result;
  if (getEventType() == EXMLEventType.StartElement) {
    _reader.next(); // Characters (the track value)
  }
  result = "";
  do {
    result += _reader.getText();
    _reader.next(); // Characters or EndElement ("string")
  } while (getEventType() == EXMLEventType.Characters);
  return result;
} // getCharactersValue()
//--------------------------------------------------------------------------------------------------
public EXMLEventType getEventType() {
  return EXMLEventType.lookupUsingStreamConstant(_reader.getEventType());
} // getEventType()
//--------------------------------------------------------------------------------------------------
public XMLStreamReader getReader() {
  return _reader;
} // getReader()
//--------------------------------------------------------------------------------------------------
}